// Every wanted to use something like Session["id"] = 12 in your Windows app like you do in ASP.NET? Now you can.
// Implements a dictionary interface. Calls look like:
AppSession.Properties["Foo"] = 1234;
if (AppSession.Properties["Foo"]!=null)
int foo = int.Parse(AppSession.Properties["Foo"]); 


--------------------------------------------------------------


class AppSession {
	// we provide one public collection, Properties
	// see below
	private AppSession() { }

	public class PropertyChangeEventArgs : EventArgs {
		private KeyValuePair<string, object> keyValuePair;
		public PropertyChangeEventArgs(KeyValuePair<string, object> keyValuePair) {
			this.keyValuePair = keyValuePair;
		}
		public System.Collections.Generic.KeyValuePair<string, object> KeyValuePair { get { return keyValuePair; } }
	}

	// event setup
	public delegate void PropertyChangeHandler(PropertyChangeEventArgs args);

	public interface IProperties : IDictionary<string, object> {
		event AppSession.PropertyChangeHandler PropertyChanged;
	}

	private class PropertiesImpl : IProperties {
		private Dictionary<string, object> dict;
		public event PropertyChangeHandler PropertyChanged;

		public PropertiesImpl() { dict = new Dictionary<string, object>(); }

		private void Fire(KeyValuePair<string, object> kv) {
			if (this.PropertyChanged != null) {
				PropertyChanged(new PropertyChangeEventArgs(kv));
			}
		}

		private void Fire(string key, object value) { Fire(new KeyValuePair<string, object>(key, value)); }

		public void Add(string key, object value) {
			if (value == null) {
				Remove(key);
			} else {
				if (ContainsKey(key)) { dict.Remove(key); }
				dict.Add(key, value);
				Fire(key, value);
			}
		}

		public bool Remove(string key) {
			bool success = dict.Remove(key);
			if (success) { Fire(key, null); }
			return success;
		}


		public object this[string key] {
			get { return (ContainsKey(key)) ? dict[key] : null; }
			set { this.Add(key, value); }
		}

		public bool ContainsKey(string key) { return dict.ContainsKey(key); }
		public ICollection<string> Keys { get { return dict.Keys; } }
		public ICollection<object> Values { get { return dict.Values; } }
		public void Add(KeyValuePair<string, object> item) { this.Add(item.Key, item.Value); }
		public bool TryGetValue(string key, out object value) { return dict.TryGetValue(key, out value); }
		public int Count { get { return dict.Count; } }
		public bool Contains(KeyValuePair<string, object> item) { return dict.Contains(item); }
		public bool IsReadOnly { get { return false; } }
		public bool Remove(KeyValuePair<string, object> item) { return Remove(item.Key); }
		public IEnumerator<KeyValuePair<string, object>> GetEnumerator() { return dict.GetEnumerator(); }
		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return dict.GetEnumerator(); }
		public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) { dict.ToArray().CopyTo(array, arrayIndex); }
		public void Clear() { new List<string>(Keys).ForEach(delegate(string key) { Remove(key); }); }

	}

	private static IProperties properties = new PropertiesImpl();
	public static IProperties Properties { get { return properties; } }

}
